/*
Package update provides functionality to implement secure, self-updating Go programs (or other single-file targets).

For complete updating solutions please see Equinox (https://equinox.io) and go-tuf (https://github.com/flynn/go-tuf).

基本示例

此示例显示了如何从URL远程更新程序。

	import (
		"fmt"
		"net/http"

		"github.com/inconshreveable/go-update"
	)

	func doUpdate(url string) error {
		// 请求新文件
		resp, err := http.Get(url)
		if err != nil {
			return err
		}
		defer resp.Body.Close()
		err := update.Apply(resp.Body, update.Options{})
		if err != nil {
			if rerr := update.RollbackError(err); rerr != nil {
				fmt.Println("Failed to rollback from bad update: %v", rerr)
			}
		}
		return err
	}

#二进制补丁

Go二进制文件通常很大。只向客户端发送二进制补丁而不是新版本的完整程序文本可能是有利的。
此示例显示了如何使用bsdiff二进制补丁更新程序。通过实现Patcher接口，可以应用其他补丁格式。

	import (
		"encoding/hex"
		"io"

		"github.com/inconshreveable/go-update"
	)

	func updateWithPatch(patch io.Reader) error {
		err := update.Apply(patch, update.Options{
			Patcher: update.NewBSDiffPatcher()
		})
		if err != nil {
			//错误处理
		}
		return err
	}

# 校验和验证

更新计算机上的可执行代码可能是一项危险的操作，除非您采取适当的措施来保证新代码的真实性。虽然校验和验证很重要，但它应该始终与签名验证（下一节）相结合，以确保代码来自受信任的一方。
go-update默认验证SHA256校验和，但这可以通过Options结构上的Hash属性进行插入。
此示例显示了如何保证新更新的二进制文件被验证为具有适当的校验和（否则将通过指定为十六进制字符串的安全通道检索校验和）。

	import (
		"crypto"
		_ "crypto/sha256"
		"encoding/hex"
		"io"

		"github.com/inconshreveable/go-update"
	)

	func updateWithChecksum(binary io.Reader, hexChecksum string) error {
		checksum, err := hex.DecodeString(hexChecksum)
		if err != nil {
			return err
		}
		err = update.Apply(binary, update.Options{
			Hash: crypto.SHA256, 	// 这是默认设置，您不需要指定它
			Checksum: checksum,
		})
		if err != nil {
			// error handling
		}
		return err
	}

# 加密签名验证

Cryptographic verification of new code from an update is an extremely important way to guarantee the
security and integrity of your updates.

Verification is performed by validating the signature of a hash of the new file. This
means nothing changes if you apply your update with a patch.

This example shows how to add signature verification to your updates. To make all of this work
an application distributor must first create a public/private key pair and embed the public key
into their application. When they issue a new release, the issuer must sign the new executable file
with the private key and distribute the signature along with the update.

	import (
		"crypto"
		_ "crypto/sha256"
		"encoding/hex"
		"io"

		"github.com/inconshreveable/go-update"
	)

	var publicKey = []byte(`
	-----BEGIN PUBLIC KEY-----
	MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEtrVmBxQvheRArXjg2vG1xIprWGuCyESx
	MMY8pjmjepSy2kuz+nl9aFLqmr+rDNdYvEBqQaZrYMc6k29gjvoQnQ==
	-----END PUBLIC KEY-----
	`)

	func verifiedUpdate(binary io.Reader, hexChecksum, hexSignature string) {
		checksum, err := hex.DecodeString(hexChecksum)
		if err != nil {
			return err
		}
		signature, err := hex.DecodeString(hexSignature)
		if err != nil {
			return err
		}
		opts := update.Options{
			Checksum: checksum,
			Signature: signature,
			Hash: crypto.SHA256, 	                 // this is the default, you don't need to specify it
			Verifier: update.NewECDSAVerifier(),   // this is the default, you don't need to specify it
		}
		err = opts.SetPublicKeyPEM(publicKey)
		if err != nil {
			return err
		}
		err = update.Apply(binary, opts)
		if err != nil {
			// error handling
		}
		return err
	}

# Building Single-File Go Binaries

In order to update a Go application with go-update, you must distributed it as a single executable.
This is often easy, but some applications require static assets (like HTML and CSS asset files or TLS certificates).
In order to update applications like these, you'll want to make sure to embed those asset files into
the distributed binary with a tool like go-bindata (my favorite): https://github.com/jteeuwen/go-bindata

# Non-Goals

Mechanisms and protocols for determining whether an update should be applied and, if so, which one are
out of scope for this package. Please consult go-tuf (https://github.com/flynn/go-tuf) or Equinox (https://equinox.io)
for more complete solutions.

go-update only works for self-updating applications that are distributed as a single binary, i.e.
applications that do not have additional assets or dependency files.
Updating application that are distributed as mutliple on-disk files is out of scope, although this
may change in future versions of this library.
*/
package update
